﻿/*************************************************************************************
 * 文 件 名:   IHK_TargetCamSystem
 * 
 * 描    述:   HK_TargetCam系统层脚本
 * 
 * 版    本：  V1.1
 * 创 建 者：  京产肠饭、谭潇杰
 * 创建时间：  2021/12/8
 * 链   接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using System.Collections.Generic;
using DG.Tweening;
using QFramework;
using UnityEngine;

namespace HKTools
{
    public interface IHK_TargetCamSystem : ISystem
    {
        /// <summary>
        /// 相机默认 移动速度
        /// </summary>
        float DefaultMoveSpeed { get; set; }

        /// <summary>
        /// 相机默认 缩放速度
        /// </summary>
        float DefaultZoomSpeed { get; set; }

        /// <summary>
        /// 是否可以控制 Camera
        /// </summary>
        bool IsCanControlCam { get; set; }

        /// <summary>
        /// 当前 控制的 Camera
        /// </summary>
        HK_TargetCamera CtrlCam { get; set; }

        /// <summary>
        /// 切换Target时，Camera运动的时间
        /// </summary>
        float CamGotoTime { get; set; }

        /// <summary>
        /// Targets 列表
        /// </summary>
        List<HK_BaseTarget> Target_List { get; set; }

        /// <summary>
        /// 当前的 Target
        /// </summary>
        HK_BaseTarget CurTarget { get; set; }

        /// <summary>
        /// 初始化 被控制的 Camera
        /// </summary>
        void InitCamera(HK_TargetCamera camera);

        /// <summary>
        /// 初始化 CamTarget列表
        /// </summary>
        void InitCamTargetList(HK_BaseTarget targetItem);

        /// <summary>
        /// 设置默认的 MoveSpeed和ZoomSpeed
        /// </summary>
        /// <param name="defaultMoveSpeed"></param>
        /// <param name="defaultZoomSpeed"></param>
        void SetDefaultSpeed(float defaultMoveSpeed, float defaultZoomSpeed);

        /// <summary>
        /// 改变 CamTarget
        /// </summary>
        void ChangeTarget(HK_TargetEnum targetType, float moveSpeed, float zoomSpeed, bool isFlash, bool isBlink, bool isLockCam);
    }

    public class HK_TargetCamSystem : AbstractSystem, IHK_TargetCamSystem
    {
        /// <summary>
        /// 相机默认 移动速度
        /// </summary>
        public float DefaultMoveSpeed { get; set; }

        /// <summary>
        /// 相机默认 缩放速度
        /// </summary>
        public float DefaultZoomSpeed { get; set; }

        /// <summary>
        /// 是否可以控制 Camera
        /// </summary>
        public bool IsCanControlCam { get; set; }

        /// <summary>
        /// 当前 控制的 Camera
        /// </summary>
        public HK_TargetCamera CtrlCam { get; set; }

        /// <summary>
        /// 切换Target时，Camera运动的时间
        /// </summary>
        public float CamGotoTime { get; set; }

        /// <summary>
        /// Targets 列表
        /// </summary>
        public List<HK_BaseTarget> Target_List { get; set; }

        /// <summary>
        /// 当前的 Target
        /// </summary>
        public HK_BaseTarget CurTarget { get; set; }

        float blinkTime = 0.4f;

        protected override void OnInit()
        {
            DefaultMoveSpeed = 2f;
            DefaultZoomSpeed = 4f;
            IsCanControlCam = true;
            CamGotoTime = 0.65f;
            Target_List = new List<HK_BaseTarget>();
        }

        /// <summary>
        /// 初始化 被控制的 Camera
        /// </summary>
        public void InitCamera(HK_TargetCamera targetCamCtrl)
        {
            this.CtrlCam = targetCamCtrl;
        }

        /// <summary>
        /// 初始化 CamTarget列表
        /// </summary>
        public void InitCamTargetList(HK_BaseTarget targetItem)
        {
            Target_List.Add(targetItem);
        }

        /// <summary>
        /// 设置默认的 MoveSpeed和ZoomSpeed
        /// </summary>
        /// <param name="defaultMoveSpeed"></param>
        /// <param name="defaultZoomSpeed"></param>
        public void SetDefaultSpeed(float defaultMoveSpeed, float defaultZoomSpeed)
        {
            DefaultMoveSpeed = defaultMoveSpeed;
            DefaultZoomSpeed = defaultZoomSpeed;

            CtrlCam.moveSpeed = defaultMoveSpeed;
            CtrlCam.zoomSpeed = defaultZoomSpeed;
        }

        Sequence blinkSequence;

        /// <summary>
        /// 改变 CamTarget
        /// </summary>
        public void ChangeTarget(HK_TargetEnum targetType, float moveSpeed, float zoomSpeed, bool isFlash, bool isBlink, bool isLockCam)
        {
            HK_BaseTarget newTarget = null;

            for (int i = 0; i < Target_List.Count; i++)
            {
                if (Target_List[i].targetType == targetType)
                    newTarget = Target_List[i];
            }

            if (newTarget == null || newTarget == CurTarget)
            {
                return;
            }

            if (blinkSequence != null)
            {
                blinkSequence.Complete();
                blinkSequence = null;
            }

            if (isFlash)
            {
                CamGotoTime = 0;
                if (isBlink)
                    blinkTime = 0.4f;
                else
                    blinkTime = 0f;
            }
            else
            {
                CamGotoTime = 0.65f;
                blinkTime = 0f;
            }

            if (blinkTime == 0.4f)
            {
                CtrlCam.ShowMask();

                blinkSequence = DOTween.Sequence()
                    .SetDelay(blinkTime)
                    .AppendCallback(() => ChangeTargetAnim(newTarget, moveSpeed, zoomSpeed));
            }
            else
            {
                ChangeTargetAnim(newTarget, moveSpeed, zoomSpeed);
            }

            if (isLockCam)
                CtrlCam.enabled = false;
            else
                CtrlCam.enabled = true;
        }

        void ChangeTargetAnim(HK_BaseTarget newTarget, float moveSpeed, float wheelSpeed)
        {
            if (CtrlCam.GetComponent<Camera>().fieldOfView != newTarget.FOV)
            {
                CtrlCam.GetComponent<Camera>().DOFieldOfView(newTarget.FOV, CamGotoTime).SetDelay(newTarget.ChangeFOV_Delay);
            }

            // 切换至新的 RotTarget 目标
            if (newTarget is HK_RotTarget)
            {
                HK_RotTarget targetItem = newTarget as HK_RotTarget;

                Quaternion lookAtRot = Quaternion.LookRotation(targetItem.targetDir, targetItem.transform.up);
                Vector3 resultEuler = lookAtRot.eulerAngles;

                CtrlCam.transform.DORotate(resultEuler, CamGotoTime);

                CtrlCam.transform.DOMove(targetItem.targetPos, CamGotoTime)
                    .OnPlay(() =>
                    {
                        // 发送 开始切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetBegin()
                        {
                            _targetEnum = targetItem.targetType
                        });
                        IsCanControlCam = false;
                    })
                    .OnComplete(() =>
                    {
                        IsCanControlCam = true;

                        // 发送 完成切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetEnd()
                        {
                            _targetEnum = targetItem.targetType
                        });
                    });

                CurTarget = newTarget;

                this.SendEvent(new Event_SwitchToRotTarget()
                {
                    _rotTargetItem = newTarget as HK_RotTarget,
                    _moveSpeed = moveSpeed,
                    _zoomSpeed = wheelSpeed
                });
            }

            // 切换至新的 AreaTarget 目标
            if (newTarget is HK_AreaTarget)
            {
                HK_AreaTarget targetItem = newTarget as HK_AreaTarget;

                Quaternion lookAtRot = Quaternion.LookRotation(targetItem.targetDir);
                Vector3 resultEuler = lookAtRot.eulerAngles;

                CtrlCam.transform.DORotate(resultEuler, CamGotoTime);

                CtrlCam.transform.DOMove(targetItem.targetPos, CamGotoTime)
                    .OnPlay(() =>
                    {
                        // 发送 开始切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetBegin()
                        {
                            _targetEnum = targetItem.targetType
                        });
                        IsCanControlCam = false;
                    })
                    .OnComplete(() =>
                    {
                        IsCanControlCam = true;

                        // 发送 完成切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetEnd()
                        {
                            _targetEnum = targetItem.targetType
                        });
                    });

                CurTarget = newTarget;

                this.SendEvent(new Event_SwitchToAreaTarget()
                {
                    _areaTargetItem = newTarget as HK_AreaTarget,
                    _moveSpeed = moveSpeed,
                    _zoomSpeed = wheelSpeed
                });
            }

            // 切换至新的 FollowTarget 目标
            if (newTarget is HK_FollowTarget)
            {
                HK_FollowTarget targetItem = newTarget as HK_FollowTarget;

                Quaternion lookAtRot = Quaternion.LookRotation(targetItem.targetDir, targetItem.transform.up);
                Vector3 resultEuler = lookAtRot.eulerAngles;

                CtrlCam.transform.DORotate(resultEuler, CamGotoTime);

                CtrlCam.transform.DOMove(targetItem.targetPos, CamGotoTime)
                    .OnPlay(() =>
                    {
                        // 发送 开始切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetBegin()
                        {
                            _targetEnum = targetItem.targetType
                        });
                        IsCanControlCam = false;
                    })
                    .OnComplete(() =>
                    {
                        IsCanControlCam = true;

                        // 发送 完成切换 Target 事件
                        this.SendEvent(new Event_SwitchTargetEnd()
                        {
                            _targetEnum = targetItem.targetType
                        });
                    });

                CurTarget = newTarget;

                this.SendEvent(new Event_SwitchToFollowTarget()
                {
                    _followTargetItem = newTarget as HK_FollowTarget,
                    _moveSpeed = moveSpeed,
                    _zoomSpeed = wheelSpeed
                });
            }
        }
    }
}